<template>
  <div>
    <a-card :bordered="false" title="无人机配送热力图分析">
      <a-spin :spinning="loading">
        <div class="map-container" id="heatMapContainer"></div>

        <div class="map-legend">
          <div class="legend-title">{{ legendTitle }}</div>
          <div class="legend-gradient"></div>
          <div class="legend-labels">
            <span>低</span>
            <span>高</span>
          </div>
        </div>

        <div class="map-controls">
          <a-form layout="inline">
            <a-form-item label="数据类型">
              <a-select v-model="dataType" style="width: 150px" @change="changeDataType">
                <a-select-option value="orders">订单分布</a-select-option>
                <a-select-option value="drones">无人机活动</a-select-option>
                <a-select-option value="delays">配送延迟</a-select-option>
              </a-select>
            </a-form-item>
            <a-form-item label="时间范围">
              <a-range-picker
                :value="dateRange"
                @change="onDateChange"
              />
            </a-form-item>
            <a-form-item label="热力强度">
              <a-input-number
                v-model="heatIntensity"
                :min="1"
                :max="5"
                :step="0.5"
                style="width: 150px"
                @change="updateHeatmapStyle"
              />
            </a-form-item>
            <a-form-item label="热力半径">
              <a-input-number
                v-model="heatRadius"
                :min="10"
                :max="50"
                :step="1"
                style="width: 150px"
                @change="updateHeatmapStyle"
              />
            </a-form-item>
            <a-form-item>
              <a-button type="primary" @click="refreshMap">刷新数据</a-button>
            </a-form-item>
          </a-form>
        </div>

        <div class="map-statistics">
          <a-row :gutter="16">
            <a-col :span="8">
              <a-statistic
                :title="dataTypeLabels[dataType] + '总数'"
                :value="totalCount"
                :precision="0"
              />
            </a-col>
            <a-col :span="8">
              <a-statistic
                title="热点区域"
                :value="hotspotCount"
                :precision="0"
                suffix="个"
              />
            </a-col>
            <a-col :span="8">
              <a-statistic
                title="覆盖范围"
                :value="coverageArea"
                :precision="2"
                suffix="平方公里"
              />
            </a-col>
          </a-row>
        </div>
      </a-spin>
    </a-card>

    <a-card :bordered="false" title="区域分析" style="margin-top: 24px">
      <a-tabs defaultActiveKey="1">
        <a-tab-pane tab="区域排名" key="1">
          <a-table
            :columns="areaColumns"
            :dataSource="areaData"
            :pagination="{ pageSize: 5 }"
            size="middle"
          >
            <template slot="count" slot-scope="text">
              <a-progress
                :percent="(text / maxAreaCount) * 100"
                :format="() => text"
                :strokeColor="getColorByDataType(dataType)"
              />
            </template>
          </a-table>
        </a-tab-pane>
        <a-tab-pane tab="时段分析" key="2">
          <div style="height: 300px">
            <div ref="timeChart" style="width: 100%; height: 300px"></div>
          </div>
        </a-tab-pane>
      </a-tabs>
    </a-card>
  </div>
</template>

<script>
// 使用 import 导入 moment
import moment from 'moment'

export default {
  name: 'HeatMap',
  data () {
    return {
      scene: null,
      layer: null,
      pointLayer: null,
      dataType: 'orders',
      dateRange: [moment().subtract(7, 'days'), moment()], // 使用 moment 对象
      loading: false,
      heatmapData: [],
      heatIntensity: 2,
      heatRadius: 20,
      totalCount: 0,
      hotspotCount: 0,
      coverageArea: 0,
      areaData: [],
      timeData: [],
      // 重庆市中心坐标
      mapCenter: [106.551556, 29.563009],
      dataTypeLabels: {
        orders: '订单',
        drones: '无人机',
        delays: '延迟'
      },
      areaColumns: [
        {
          title: '排名',
          dataIndex: 'rank',
          key: 'rank',
          width: 80
        },
        {
          title: '区域',
          dataIndex: 'name',
          key: 'name'
        },
        {
          title: '数量',
          dataIndex: 'count',
          key: 'count',
          scopedSlots: { customRender: 'count' }
        }
      ]
    }
  },
  mounted () {
    this.initMap()
  },
  beforeDestroy () {
    if (this.scene) {
      this.scene.destroy()
    }
  },
  methods: {
    initMap () {
      // 使用高德地图原生API初始化地图
      this.loading = true

      // 确保高德地图API已加载
      if (window.AMap) {
        this.createMap()
      } else {
        // 如果API未加载，等待加载完成
        const checkAMap = setInterval(() => {
          if (window.AMap) {
            clearInterval(checkAMap)
            this.createMap()
          }
        }, 100)
      }
    },

    createMap () {
      // 创建高德地图实例，使用重庆市坐标
      const map = new window.AMap.Map('heatMapContainer', {
        center: this.mapCenter, // 使用重庆市中心坐标
        zoom: 11,
        viewMode: '2D',
        mapStyle: 'amap://styles/dark', // 使用深色地图样式
        features: ['bg', 'road', 'building', 'point'] // 保留基本要素
      })

      // 添加控件
      map.plugin(['AMap.ToolBar', 'AMap.Scale'], () => {
        map.addControl(new window.AMap.ToolBar())
        map.addControl(new window.AMap.Scale())
      })

      // 创建热力图实例
      map.plugin(['AMap.HeatMap'], () => {
        // 初始化热力图
        const heatmap = new window.AMap.HeatMap(map, {
          radius: this.heatRadius, // 热力图半径
          opacity: [0, 0.8], // 热力图透明度
          gradient: {
            0.1: 'rgb(0, 255, 0)', // 绿色开始
            0.3: 'rgb(144, 238, 144)', // 浅绿色
            0.5: 'rgb(255, 255, 0)', // 黄色
            0.7: 'rgb(255, 165, 0)', // 橙色
            0.9: 'rgb(255, 0, 0)' // 红色结束
          }
        })

        this.heatmap = heatmap
        this.map = map

        // 加载热力图数据
        this.loadHeatmapData()

        // 地图加载完成
        map.on('complete', () => {
          console.log('地图加载完成')
        })
      })
    },

    loadHeatmapData () {
      this.loading = true

      // 模拟从API获取数据
      setTimeout(() => {
        // 生成模拟数据
        const data = this.generateMockData()

        // 转换为高德热力图需要的格式
        const heatmapData = data.map(item => {
          return {
            lng: item.lng,
            lat: item.lat,
            count: item.count
          }
        })

        this.heatmapData = data

        // 设置热力图数据
        if (this.heatmap) {
          this.heatmap.setDataSet({
            data: heatmapData,
            max: 100
          })
        }

        // 生成统计数据
        this.generateStatistics()
        this.generateAreaData()
        this.generateTimeData()

        this.loading = false
      }, 500)
    },

    generateMockData () {
      // 使用重庆市中心坐标生成热力图数据
      const center = this.mapCenter
      const data = []

      // 增加数据点数量
      let points = 3000 // 增加到3000个点
      let radius = 0.08 // 扩大覆盖半径
      let clusters = 8 // 增加聚集区数量

      if (this.dataType === 'drones') {
        points = 2500
        radius = 0.06
        clusters = 6
      } else if (this.dataType === 'delays') {
        points = 1500
        radius = 0.05
        clusters = 5
      }

      // 生成主要聚集中心
      const clusterCenters = []

      // 重庆市主要区域坐标 (渝中区、江北区、南岸区等)
      const majorAreas = [
        { name: '渝中区', coords: [106.568891, 29.552756] },
        { name: '江北区', coords: [106.574271, 29.606703] },
        { name: '南岸区', coords: [106.644428, 29.500359] },
        { name: '沙坪坝区', coords: [106.456543, 29.541224] },
        { name: '九龙坡区', coords: [106.510676, 29.502272] },
        { name: '渝北区', coords: [106.631187, 29.718143] },
        { name: '巴南区', coords: [106.540257, 29.402408] },
        { name: '北碚区', coords: [106.395612, 29.805108] }
      ]

      // 使用真实区域坐标作为聚集中心
      for (let i = 0; i < Math.min(clusters, majorAreas.length); i++) {
        clusterCenters.push({
          lng: majorAreas[i].coords[0],
          lat: majorAreas[i].coords[1],
          name: majorAreas[i].name,
          weight: Math.random() * 0.5 + 0.5 // 权重因子，影响该区域的点密度
        })
      }

      // 如果需要更多聚集中心，随机生成
      for (let i = majorAreas.length; i < clusters; i++) {
        clusterCenters.push({
          lng: center[0] + (Math.random() - 0.5) * 0.2,
          lat: center[1] + (Math.random() - 0.5) * 0.2,
          name: `区域${i + 1}`,
          weight: Math.random() * 0.5 + 0.5
        })
      }

      // 围绕聚集点生成数据，使用更自然的分布
      for (let i = 0; i < points; i++) {
        // 随机选择一个聚集中心，使用加权随机
        let clusterIndex

        // 20%的点完全随机分布，不依附于聚集中心
        if (Math.random() < 0.2) {
          // 在整个区域随机生成点
          const randomLng = center[0] + (Math.random() - 0.5) * radius * 4
          const randomLat = center[1] + (Math.random() - 0.5) * radius * 4
          const count = Math.floor(Math.random() * 40) + 10 // 随机点的热度较低

          data.push({
            lng: randomLng,
            lat: randomLat,
            count,
            cluster: -1 // 标记为随机点
          })

          continue
        }

        // 对于其余80%的点，根据权重选择聚集中心
        const weights = clusterCenters.map(c => c.weight)
        const totalWeight = weights.reduce((sum, w) => sum + w, 0)
        let random = Math.random() * totalWeight

        for (clusterIndex = 0; clusterIndex < clusterCenters.length; clusterIndex++) {
          random -= weights[clusterIndex]
          if (random <= 0) break
        }

        if (clusterIndex >= clusterCenters.length) {
          clusterIndex = clusterCenters.length - 1
        }

        const clusterCenter = clusterCenters[clusterIndex]

        // 使用正态分布生成距离，使点更集中在中心附近
        // Box-Muller变换生成正态分布
        const u1 = Math.random()
        const u2 = Math.random()
        const z0 = Math.sqrt(-2.0 * Math.log(u1)) * Math.cos(2.0 * Math.PI * u2)
        const distance = Math.abs(z0) * radius * 0.4 // 缩小标准差，使点更集中

        // 随机角度
        const angle = Math.random() * Math.PI * 2

        const lng = clusterCenter.lng + distance * Math.cos(angle)
        const lat = clusterCenter.lat + distance * Math.sin(angle)

        // 生成计数值，靠近中心的点计数值更高，但加入一些随机性
        const distanceFactor = Math.max(0, 1 - distance / radius)
        const baseFactor = 0.7 // 基础因子，确保即使在边缘也有一定热度
        const randomFactor = Math.random() * 0.3 // 随机因子，增加变化性

        // 根据数据类型调整热度
        let countMultiplier = 1
        if (this.dataType === 'orders') {
          countMultiplier = 1.2
        } else if (this.dataType === 'delays') {
          countMultiplier = 0.8
        }

        const count = Math.floor(((baseFactor + distanceFactor + randomFactor) * 100) * countMultiplier)

        data.push({
          lng,
          lat,
          count,
          cluster: clusterIndex,
          areaName: clusterCenter.name
        })
      }

      // 添加一些特殊热点，模拟商业中心、交通枢纽等
      const hotspots = [
        { name: '解放碑', coords: [106.577196, 29.557096], factor: 1.5 },
        { name: '观音桥', coords: [106.531926, 29.575352], factor: 1.4 },
        { name: '江北国际机场', coords: [106.640224, 29.719639], factor: 1.3 },
        { name: '重庆北站', coords: [106.531463, 29.601564], factor: 1.3 },
        { name: '重庆西站', coords: [106.311395, 29.825457], factor: 1.2 }
      ]

      // 在热点周围添加高密度点
      hotspots.forEach(hotspot => {
        const hotspotPoints = Math.floor(points * 0.05) // 每个热点额外5%的点
        for (let i = 0; i < hotspotPoints; i++) {
          // 使用更小的半径，确保点更集中
          const distance = Math.random() * radius * 0.2
          const angle = Math.random() * Math.PI * 2

          const lng = hotspot.coords[0] + distance * Math.cos(angle)
          const lat = hotspot.coords[1] + distance * Math.sin(angle)

          // 热点区域的点热度更高
          const count = Math.floor((Math.random() * 50 + 50) * hotspot.factor)

          data.push({
            lng,
            lat,
            count,
            cluster: -2, // 标记为热点
            hotspot: hotspot.name
          })
        }
      })

      return data
    },

    generateStatistics () {
      // 计算总数
      this.totalCount = this.heatmapData.length

      // 计算热点数量 (计数值大于70的点)
      this.hotspotCount = this.heatmapData.filter(item => item.count > 70).length

      // 计算覆盖面积 (简化计算)
      const minLng = Math.min(...this.heatmapData.map(item => item.lng))
      const maxLng = Math.max(...this.heatmapData.map(item => item.lng))
      const minLat = Math.min(...this.heatmapData.map(item => item.lat))
      const maxLat = Math.max(...this.heatmapData.map(item => item.lat))

      // 简单估算面积 (平方公里)
      const width = (maxLng - minLng) * 111.32 * Math.cos(minLat * Math.PI / 180)
      const height = (maxLat - minLat) * 111.32
      this.coverageArea = width * height
    },

    generateAreaData () {
      // 模拟重庆市区域数据
      const areas = [
        '渝中区', '江北区', '南岸区', '沙坪坝区', '九龙坡区',
        '大渡口区', '渝北区', '巴南区', '北碚区', '万州区'
      ]

      this.areaData = areas.map((name, index) => {
        return {
          key: index,
          rank: index + 1,
          name,
          count: Math.floor(Math.random() * 500) + 100
        }
      }).sort((a, b) => b.count - a.count)

      // 重新排序
      this.areaData.forEach((item, index) => {
        item.rank = index + 1
      })
    },

    generateTimeData () {
      // 生成24小时的时间数据
      this.timeData = []
      for (let i = 0; i < 24; i++) {
        let count
        // 模拟不同时段的数据分布
        if (i >= 8 && i <= 12) {
          // 上午高峰
          count = Math.floor(Math.random() * 100) + 150
        } else if (i >= 17 && i <= 21) {
          // 晚上高峰
          count = Math.floor(Math.random() * 120) + 180
        } else if (i >= 1 && i <= 5) {
          // 凌晨低谷
          count = Math.floor(Math.random() * 30) + 20
        } else {
          // 其他时段
          count = Math.floor(Math.random() * 70) + 80
        }

        this.timeData.push({
          time: `${i}:00`,
          count
        })
      }

      // 如果有echarts，可以绘制时间图表
      this.$nextTick(() => {
        if (window.echarts && this.$refs.timeChart) {
          const chart = window.echarts.init(this.$refs.timeChart)
          chart.setOption({
            tooltip: {
              trigger: 'axis'
            },
            xAxis: {
              type: 'category',
              data: this.timeData.map(item => item.time)
            },
            yAxis: {
              type: 'value'
            },
            series: [{
              data: this.timeData.map(item => item.count),
              type: 'line',
              smooth: true,
              lineStyle: {
                color: this.getColorByDataType(this.dataType)
              },
              itemStyle: {
                color: this.getColorByDataType(this.dataType)
              }
            }]
          })
        }
      })
    },

    changeDataType (value) {
      this.dataType = value

      // 更新热力图渐变色
      if (this.heatmap) {
        this.heatmap.setOptions({
          gradient: {
            0.1: 'rgb(0, 255, 0)', // 绿色开始
            0.3: 'rgb(144, 238, 144)', // 浅绿色
            0.5: 'rgb(255, 255, 0)', // 黄色
            0.7: 'rgb(255, 165, 0)', // 橙色
            0.9: 'rgb(255, 0, 0)' // 红色结束
          }
        })
      }

      this.loadHeatmapData()
    },

    onDateChange (dates) {
      this.dateRange = dates
      this.refreshMap()
    },

    refreshMap () {
      this.loadHeatmapData()
    },

    updateHeatmapStyle () {
      if (this.heatmap) {
        this.heatmap.setOptions({
          radius: this.heatRadius,
          gradient: {
            0.1: 'rgb(0, 255, 0)', // 绿色开始
            0.3: 'rgb(144, 238, 144)', // 浅绿色
            0.5: 'rgb(255, 255, 0)', // 黄色
            0.7: 'rgb(255, 165, 0)', // 橙色
            0.9: 'rgb(255, 0, 0)' // 红色结束
          }
        })
      }
    },

    getColorByDataType (type) {
      const colors = {
        orders: '#1890ff',
        drones: '#52c41a',
        delays: '#f5222d'
      }

      return colors[type] || colors.orders
    },

    // 修改颜色映射方法
    getColorsForDataType () {
      const colorMaps = {
        orders: [
          '#00FF00', '#90EE90', '#FFFF00', '#FFA500', '#FF0000'
        ],
        drones: [
          '#00FF00', '#90EE90', '#FFFF00', '#FFA500', '#FF0000'
        ],
        delays: [
          '#00FF00', '#90EE90', '#FFFF00', '#FFA500', '#FF0000'
        ]
      }

      return colorMaps[this.dataType] || colorMaps.orders
    }
  },
  computed: {
    legendTitle () {
      return this.dataTypeLabels[this.dataType] + '密度'
    },
    maxAreaCount () {
      return this.areaData.length > 0 ? this.areaData[0].count : 100
    }
  },
  watch: {
    dataType () {
      // 更新图例样式
      this.$nextTick(() => {
        const legendEl = document.querySelector('.legend-gradient')
        if (legendEl) {
          legendEl.style.background = 'linear-gradient(to right, #00FF00, #90EE90, #FFFF00, #FFA500, #FF0000)'
        }
      })
    }
  }
}
</script>

<style scoped>
.map-container {
  width: 100%;
  height: 600px;
  position: relative;
}

.map-controls {
  margin-top: 16px;
  margin-bottom: 16px;
  background-color: white;
  padding: 16px;
  border-radius: 4px;
  color: black;
}

.map-statistics {
  margin-top: 16px;
  background-color: white;
  padding: 16px;
  border-radius: 4px;
  color: black;
}

.map-legend {
  position: absolute;
  bottom: 30px;
  right: 30px;
  background: rgba(0, 0, 0, 0.7);
  padding: 10px;
  border-radius: 4px;
  z-index: 1000;
  width: 200px;
  color: white;
}

.legend-title {
  font-size: 12px;
  margin-bottom: 5px;
  color: white;
}

.legend-gradient {
  height: 10px;
  width: 100%;
  background: linear-gradient(to right, #00FF00, #90EE90, #FFFF00, #FFA500, #FF0000);
  border-radius: 2px;
}

.legend-labels {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
  margin-top: 5px;
  color: white;
}
</style>
